package api

import (
	"beta/pkg/app"
	"beta/pkg/e"
	"beta/pkg/util"
	"beta/service/boss_service"
	"beta/service/customer_service"
	"beta/service/env_service"
	"beta/service/nbgl2_service"
	"beta/service/opc_service"
	"beta/service/otcpro_service"
	"github.com/gin-gonic/gin"
	"github.com/srlemon/gen-id/generator"
	"net/http"
	"strconv"
	"time"
)

type AddOrderForm struct {
	Operator      string `json:"operator" valid:"Required"`
	Namespace     string `json:"namespace" valid:"Required"`
	DepositNum    string `json:"depositNum" valid:"Required"`
	OrderType 	  int `json:"orderType"`
	Account struct {
		ProductId string
	} `json:"account"`
	CashDeposit struct {
		PayFlag bool `json:"payFlag"`
	} `json:"cashDeposit"`
	CouponDeposit struct {
		Audit bool
		Flag bool
	} `json:"couponDeposit"`
	OrdinaryOrder struct {
		ProductID        string `json:"productId"`
		ProductVersionID string `json:"productVersionId"`
		StartDate        string `json:"startDate"`
		EndDate          string `json:"endDate"`
	} `json:"ordinaryOrder"`
	SettleOrder struct {
		ProductID        string `json:"productId"`
		ProductVersionID string `json:"productVersionId"`
	} `json:"settleOrder"`
}


var (
	g = new(generator.GeneratorData)
)

func AddOrder(c *gin.Context) {

	traceId := util.GetTraceID(c)
	bankId := g.GeneratorBankID()

	receiverMobile := g.GeneratorPhone()
	receiverEmail := "11@qq.com"

	var (
		appG = app.Gin{C: c}
		form AddOrderForm
	)

	httpCode, errCode := app.BindAndValid(c, &form, traceId)
	if errCode != e.SUCCESS {
		appG.Response(httpCode, errCode, traceId, nil)
		return
	}
	data := make(map[string]interface{})

	fullName := form.Namespace + "-beta-autotest-" + strconv.Itoa(int(time.Now().Unix()))

	data["fullName"] = fullName
	data["namespace"] = form.Namespace

	envService := env_service.EnvService{
		TraceId:   traceId,
	}

	hosts, hostsErr := envService.GetAllAppEnvsWithNamespace(form.Namespace)
	if hostsErr != nil {
		appG.Response(http.StatusInternalServerError, e.EnvErr, traceId, nil)
		return
	}

	customerService := customer_service.CustomerService{
		FullName: fullName,
		Hosts:    hosts,
		TraceId:  traceId,
	}

	customerId, customerIdErr := customerService.AddCustomer()
	if customerIdErr != nil {
		appG.Response(http.StatusInternalServerError, e.CustomerCreateErr, traceId, nil)
		return
	}
	data["customerId"] = customerId

	bossService := boss_service.BossService{
		Operator: form.Operator,
		Hosts:    hosts,
		TraceId:  traceId,
	}

	token, bossErr := bossService.Login()
	if bossErr != nil {
		appG.Response(http.StatusInternalServerError, e.BossTokenErr, traceId, nil)
		return
	}
	
	data["token"] = token



	nbService := nbgl2_service.Nbgl2Service{
		Hosts:   hosts,
		TraceId: traceId,
	}

	nbErr := nbService.AddCash(fullName, bankId, form.DepositNum)
	if nbErr != nil {
		appG.Response(http.StatusInternalServerError, e.Nbgl2AddCashErr, traceId, nil)
		return
	}

	opcService := opc_service.OpcService{
		FullName:       fullName,
		CustomerID:     customerId,
		DepositNum: 	form.DepositNum,
		Operator:       form.Operator,
		ReceiverMobile: receiverMobile,
		ReceiverEmail:  receiverEmail,
		Token:          token,
		Hosts:          hosts,
		TraceId:        traceId,
	}

	remittanceId, remittanceIdErr := opcService.QueryRemittance(fullName, bankId)
	if remittanceIdErr != nil {
		appG.Response(http.StatusInternalServerError, e.OpcQueryRemittanceErr, traceId, nil)
		return
	}

	data["remittanceId"] = remittanceId
	data["bankId"] = bankId

	if form.OrderType == 0  {
		appG.Response(http.StatusOK, e.SUCCESS, traceId, data)
		return
	}

	accountProductId := form.Account.ProductId
	accountIdStr, accountErr := opcService.AddAccount(accountProductId)
	accountId, _ := strconv.Atoi(accountIdStr)

	if accountErr != nil {
		appG.Response(http.StatusInternalServerError, e.OpcAccountCreateErr, traceId, nil)
		return
	}

	data["accountId"] = accountId

	cashDepositId, cashDepositIdErr := opcService.AddDepositBill(accountId, remittanceId, "1", form.CashDeposit.PayFlag)
	if cashDepositIdErr != nil {
		appG.Response(http.StatusInternalServerError, e.OpcCashOrderCreateErr, traceId, nil)
		return
	}
	data["cash_depositId"] = cashDepositId

	couponDepositId, couponDepositIdErr := opcService.AddDepositBill(accountId, "","2", form.CashDeposit.PayFlag)
	if couponDepositIdErr != nil {
		appG.Response(http.StatusInternalServerError, e.OpcCouponOrderCreateErr, traceId, nil)
		return
	}
	data["coupon_depositId"] = couponDepositId

	if form.CouponDeposit.Audit == true {
		couponAuditErr := opcService.Audit(couponDepositId, form.CouponDeposit.Flag)
		if couponAuditErr != nil {
			appG.Response(http.StatusInternalServerError, e.OpcCouponAuditErr, traceId, nil)
			return
		}
	}

	otcproService := otcpro_service.OtcProService{
		FullName: fullName,
		CustomerId:     customerId,
		ReceiverEmail:  receiverEmail,
		ReceiverMobile: receiverMobile,
		Operator:       form.Operator,
		Token:          token,
		Hosts:          hosts,
	}

	if form.OrderType == 1  {
		productId := form.OrdinaryOrder.ProductID
		productVersionId := form.OrdinaryOrder.ProductVersionID
		startDate := form.OrdinaryOrder.StartDate
		endDate := form.OrdinaryOrder.EndDate
		ordinaryOrderId, ordinaryErr:= otcproService.CreateOrdinaryOrder(productId, productVersionId, startDate, endDate)
		if ordinaryErr != nil {
			appG.Response(http.StatusInternalServerError, e.OtcProOrdinaryCreateErr, traceId, nil)
			return
		}
		data["ordinaryOrderId"] = ordinaryOrderId
	}

	if form.OrderType == 2 {
		productId := form.SettleOrder.ProductID
		productVersionId := form.SettleOrder.ProductVersionID
		settleOrderId, settleErr := otcproService.CreateSettleOrder(productId, productVersionId)
		if settleErr != nil {
			appG.Response(http.StatusInternalServerError, e.OtcProSettleCreateErr, traceId, nil)
			return
		}
		data["settleOrderId"] = settleOrderId
	}

	//
	//oecService := oec_service.OecService{
	//	Hosts:   hosts,
	//	TraceId: traceId,
	//}
	//
	//oecErr := oecService.AddConsumeData(customerId)
	//if oecErr != nil {
	//	appG.Response(http.StatusInternalServerError, e.OecAddConsumeDataErr, traceId, nil)
	//	return
	//}

	appG.Response(http.StatusOK, e.SUCCESS, traceId, data)

}